package com.insight.common.system.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.base.Joiner;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.mapper.BaseCommonMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @Description: JWT工具类，提供Token生成、校验、解析等相关方法
 * @Author: 自动补全
 * @Date: 2024-07-01
 */
@Component
public class JwtUtil {

	@Autowired
	private   BaseCommonMapper baseCommonMapper;
	// Token过期时间30分钟（以token在reids缓存时间为准）

	/**
	 * 获取Token过期时间，单位秒
	 * @return 过期时间（秒）
	 */
	public long getTime (){

		if (StringUtils.isEmpty(baseCommonMapper.findOverTime())){
			return 30*60;
		}
		return Long.parseLong(baseCommonMapper.findOverTime())*60;
	}

	/**
	 * 校验token是否正确
	 * @param token 密钥
	 * @param username 用户名
	 * @param secret 用户的密码
	 * @return 是否正确
	 */
	public static boolean verify(String token, String username, String secret) {
		try {
			if (token == null || username == null || secret == null) {
				return false;
			}
			// 根据密码生成JWT效验器
			Algorithm algorithm = Algorithm.HMAC256(secret);
			JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
			// 效验TOKEN
			verifier.verify(token);
			return true;
		} catch (Exception exception) {
			return false;
		}
	}

	/**
	 * 获得token中的信息，无需secret解密也能获得
	 * @param token token字符串
	 * @return token中包含的用户名
	 */
	public static String getUsername(String token) {
		try {
			DecodedJWT jwt = JWT.decode(token);
			String username = jwt.getClaim("username").asString();
			if(StringUtils.isEmpty(username)){
				username = jwt.getClaim("user_name").asString();
			}
			return username;
		} catch (JWTDecodeException e) {
			return null;
		}
	}

	/**
	 * 生成签名，5分钟后过期
	 * @param username 用户名
	 * @param secret 用户的密码
	 * @return 加密的token
	 */
	public String sign(String username, String secret) {

		System.out.println(this.getTime());
		Algorithm algorithm = Algorithm.HMAC256(secret);
		// 附带username信息
		return JWT.create().withClaim("username", username).withExpiresAt(new Date(System.currentTimeMillis() + this.getTime())).sign(algorithm);

	}

	/**
	 * 根据request中的token获取用户账号
	 * @param request HttpServletRequest请求
	 * @return 用户账号
	 * @throws JeecgBootException 未获取到用户时抛出
	 */
	public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException {
		String accessToken = request.getHeader("X-Access-Token");
		String username = getUsername(accessToken);
		if (oConvertUtils.isEmpty(username)) {
			throw new JeecgBootException("未获取到用户");
		}
		return username;
	}

	/**
	 * 从session中获取变量
	 * @param key 变量名
	 * @return 变量值
	 */
	public static String getSessionData(String key) {
		//${myVar}%
		//得到${} 后面的值
		String moshi = "";
		if(key.indexOf('}')!=-1){
			moshi = key.substring(key.indexOf('}')+1);
		}
		String returnValue = null;
		if (key.contains("#{")) {
			key = key.substring(2,key.indexOf('}'));
		}
		if (oConvertUtils.isNotEmpty(key)) {
			HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
			returnValue = (String) session.getAttribute(key);
		}
		//结果加上${} 后面的值
		if(returnValue!=null){returnValue = returnValue + moshi;}
		return returnValue;
	}

	/**
	 * 从当前用户中获取变量
	 * @param key 变量名
	 * @param user 用户缓存信息
	 * @return 变量值
	 */
	//TODO 急待改造 sckjkdsjsfjdk
	public static String getUserSystemData(String key, SysUserCacheInfo user) {
		if (user == null) {
			user = JeecgDataAutorUtils.loadUserInfo();
		}

		// 提取可能存在的后缀（如"}"后的内容）
		String moshi = "";
		int suffixIndex = key.indexOf('}');
		if (suffixIndex != -1) {
			moshi = key.substring(suffixIndex + 1);
			key = key.substring(0, suffixIndex); // 移除后缀部分
		}

		// 提取变量名（移除"#{"前缀）
		String varName = key;
		if (key.startsWith("#{")) {
			varName = key.substring(2);
		}

		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		String returnValue = "";

		// 根据变量名匹配预定义常量
		if (varName.equals(DataBaseConstant.SYS_USER_CODE) || varName.equalsIgnoreCase(DataBaseConstant.SYS_USER_CODE_TABLE)) {
			returnValue = (user == null) ? sysUser.getUsername() : user.getSysUserCode();
		}
		else if (varName.equals(DataBaseConstant.SYS_USER_NAME) || varName.equalsIgnoreCase(DataBaseConstant.SYS_USER_NAME_TABLE)) {
			returnValue = (user == null) ? sysUser.getRealname() : user.getSysUserName();
		}
		else if (varName.equals(DataBaseConstant.SYS_ORG_CODE) || varName.equalsIgnoreCase(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
			returnValue = (user == null) ? sysUser.getOrgCode() : user.getSysOrgCode();
		}
		else if (varName.equals(DataBaseConstant.SYS_MULTI_ORG_CODE) || varName.equalsIgnoreCase(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
			if (user == null) {
				returnValue = sysUser.getOrgCode(); // 临时使用登录部门
			} else {
				returnValue = user.isOneDepart()
						? user.getSysMultiOrgCode().get(0)
						: String.join(",", user.getSysMultiOrgCode());
			}
		}
		else if (varName.equals(DataBaseConstant.SYS_DATE) || varName.equalsIgnoreCase(DataBaseConstant.SYS_DATE_TABLE)) {
			returnValue = DateUtils.formatDate();
		}
		else if (varName.equals(DataBaseConstant.SYS_TIME) || varName.equalsIgnoreCase(DataBaseConstant.SYS_TIME_TABLE)) {
			returnValue = DateUtils.now();
		}
		else if (varName.equals(DataBaseConstant.BPM_STATUS) || varName.equalsIgnoreCase(DataBaseConstant.BPM_STATUS_TABLE)) {
			returnValue = "1"; // 流程状态默认值
		}

		// 追加后缀（如果存在）
		return returnValue + moshi;
	}

//	public static void main(String[] args) {
//		 String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0";
//		 System.out.println(JwtUtil.getUsername(token));
//	}

	public static void main(String[] args) {
		String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3NDcwNDg1ODgsInVzZXJuYW1lIjoiYWRtaW4ifQ.XWv6SpjRIDlHGjOIyrOC9YslmWVWXZRelkfDcNfXF8s";
		System.out.println(JwtUtil.getUsername(token));
	}
}
